#include <gtest/gtest.h>

#include <compilation/Program.h>
#include <compilation/task/PrintTask.h>
#include <compilation/instruction/InstructionVisitor.h>


extern FILE *yyin;
extern int yyparse();
extern int yydebug;
extern compilation::Program::ParseContext parseContext;


compilation::Program program;


namespace compilation
{


typedef
InstructionVisitor<void, PrintTask&, PrintAgenda&, WorkListReusability&>
    print_handler_visitor;


TEST(PrintHandler, can_be_executed)
{
  PrintAgenda::instruction_handler_visitor_type phv =
      PrintAgenda::instruction_handler_visitor_type
      ::build_visitor<PrintHandler>();

  PrintAgenda::instruction_propagator_visitor_type ppv =
      PrintAgenda::instruction_propagator_visitor_type
      ::build_visitor<DefaultInstructionPropagator<PrintTask, PrintAgenda>::type>();

  std::stringstream ss;
  PrintAgenda ag(phv, ppv, ss, *program.get_functions().begin());
  execute(ag);
  std::string expect =
      "  0   {\n"
      "  1     return ([parameter 0: x] + 2);\n";
  EXPECT_EQ(expect, ss.str());
}


} // compilation


int main(int argc, char** argv)
{
  ::testing::InitGoogleTest(&argc, argv);

  if (argc < 2) return 1;

  parseContext.setProgram(program);

  if (argc > 1) yyin = fopen(argv[1], "r");

  while (yyparse() != 0);

  return RUN_ALL_TESTS();
}
